package com.ewancle.proxydownload.filter;

import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.List;

@Component
public class GlobalWebFilter implements WebFilter {

    private final Environment env;
    private final WebClient webClientNoRedirect;

    public GlobalWebFilter(Environment env, WebClient webClientNoRedirect) {
        this.env = env;
        this.webClientNoRedirect = webClientNoRedirect;
    }

    private final List<String> candidateUrls = List.of(
            "https://cdn1.example.com/image.jpg",
            "https://cdn2.example.com/image.jpg",
            "https://cdn3.example.com/image.jpg"
    );

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

        String value2 = System.getProperty("user.timezone"); // JVM 启动参数或系统属性
        String mode = env.getProperty("my.image.mode"); // 来自 application.yml、-D、ENV都可以
        String javaHome = env.getProperty("JAVA_HOME"); // 来自操作系统环境变量

        ServerHttpRequest request = exchange.getRequest();

        if ("/favicon.ico".equals(exchange.getRequest().getPath().value())) {
            exchange.getResponse().setStatusCode(HttpStatus.NO_CONTENT); // 204
            return exchange.getResponse().setComplete();
        }

        // 不是/img-proxy 开头请求直接放行
       if (!exchange.getRequest().getPath().value().startsWith("/img-proxy")) {
            return chain.filter(exchange);
        }

        // 请求日志记录
        String path = request.getURI().getPath();
        System.out.println("🌐 WebFilter 处理请求路径: " + path);

        // 示例：将 /old 路径重定向到 /new 这是指：告诉浏览器去请求另一个地址（客户端跳转，HTTP 302/301）
        // 301 为 MOVED_PERMANENTLY
        if ("/youtube".equals(path)) {
            exchange.getResponse().setStatusCode(HttpStatus.FOUND); // 302
            //exchange.getResponse().getHeaders().setLocation(URI.create("/new"));
            exchange.getResponse().getHeaders().setLocation(URI.create("https://www.youtube.com/"));
            return exchange.getResponse().setComplete();
        }

        /*
        这种方式仅适用于你控制了处理链（比如 @RequestMapping("/api/target") 存在）。
        不发起新请求，仍然是 服务端内部跳转（伪转发）。*/
        if ("/api/forward".equals(path)) {
            // 转发到 /api/target
            ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
                    .path("/api/target")
                    .build();
            ServerWebExchange mutatedExchange = exchange.mutate()
                    .request(mutatedRequest)
                    .build();
            return chain.filter(mutatedExchange);
        }

        // 示例：校验 Header 是否包含某个 token
        String token = exchange.getRequest().getHeaders().getFirst("X-Auth-Token");
        /*if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }*/


        return Flux.fromIterable(candidateUrls)
                .flatMap(this::tryDirectFetchHead, 3)
                .next() // 只取第一个成功的
                .flatMap(directUrl -> {
                    // 示例：重定向到选中的 CDN
                    exchange.getResponse().setStatusCode(HttpStatus.FOUND);
                    exchange.getResponse().getHeaders().setLocation(URI.create(directUrl));
                    return exchange.getResponse().setComplete();
                })
                /*.switchIfEmpty(
                        Mono.fromRunnable(() -> exchange.getResponse().setStatusCode(HttpStatus.SERVICE_UNAVAILABLE))
                                .then(exchange.getResponse().setComplete())
                );*/
                .switchIfEmpty(
                        Mono.defer(() -> {
                            exchange.getResponse().setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
                            return exchange.getResponse().setComplete();
                        })
                );

        // 放行
        /*return chain.filter(exchange)
                .doOnSuccess((done) -> System.out.println("✅ 响应返回完毕"))
                .doOnError((ex) -> System.err.println("❌ 异常: " + ex.getMessage()));*/
    }


    private Mono<String> tryDirectFetchHead(String url) {
        return webClientNoRedirect
                .head()
                .uri(url)
                .exchangeToMono(response -> {
                    HttpStatusCode status = response.statusCode();
                    if (status.is2xxSuccessful()) {
                        return Mono.just(url);
                    } else if (status.is3xxRedirection()) {
                        // 明确排除重定向响应
                        System.out.println("🔁 跳过重定向 URL: " + url + " → " + status);
                        return Mono.empty();
                    } else {
                        return Mono.empty();
                    }
                })
                .onErrorResume(e -> {
                    System.out.println("❌ 请求失败: " + url + " - " + e.getMessage());
                    return Mono.empty();
                });
    }
}

